package org.jeecg.modules.hc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.hc.constant.RedisConstant;
import org.jeecg.modules.hc.entity.HcCommodity;
import org.jeecg.modules.hc.entity.HcMerchantCommission;
import org.jeecg.modules.hc.entity.HcSiteAddressDetails;
import org.jeecg.modules.hc.enums.HcIsFlagEnum;
import org.jeecg.modules.hc.mapper.HcCommodityMapper;
import org.jeecg.modules.hc.service.IHcCommodityService;
import org.jeecg.modules.hc.service.IHcMerchantCommissionService;
import org.jeecg.modules.hc.service.IHcOrderDetailedService;
import org.jeecg.modules.hc.service.IHcSiteAddressDetailsService;
import org.jeecg.modules.hc.utils.HcUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * author作者：lilingjie
 */
@Service
public class HcCommodityServiceImpl extends ServiceImpl<HcCommodityMapper, HcCommodity> implements IHcCommodityService {

    @Resource
    private HcCommodityMapper hcCommodityMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IHcOrderDetailedService hcOrderDetailedService;

    @Autowired
    private IHcSiteAddressDetailsService hcSiteAddressDetailsService;

    @Autowired
    private IHcMerchantCommissionService hcMerchantCommissionService;

    @Override
    public IPage<HcCommodity> pageList(Page<HcCommodity> page, HcCommodity param) {
        return hcCommodityMapper.pageList(page, param);
    }

    @Override
    public void checkCommodity(HcCommodity hcCommodity) {
        JSONArray jsonArray = JSON.parseArray(hcCommodity.getCommoditySpecifications());

        int zeroCount = 0;
        boolean nullFlag = false;

        if (jsonArray != null) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray child = jsonObject.getJSONArray("child");
                boolean zeroFlag = false;

                for (int i1 = 0; i1 < child.size(); i1++) {
                    JSONObject childJSONObject = child.getJSONObject(i1);
                    String name = childJSONObject.getString("name");
                    BigDecimal price = childJSONObject.getBigDecimal("price");

                    if (StringUtils.isBlank(name)) {
                        throw new JeecgBootException("规格名称不能为空");
                    }

                    if (price == null) {
                        nullFlag = true;
                        zeroFlag = true;
                    } else if (price.compareTo(new BigDecimal(0)) <0) {
//                    } else if (price.compareTo(new BigDecimal(0)) <= 0) {
                        zeroFlag = true;
                    }
                }

                if (zeroFlag) zeroCount++;
            }
        }

        if (hcCommodity.getCommodityPrice() == null && nullFlag) {
            throw new JeecgBootException("规格价格不能为空");
        } else if (hcCommodity.getSpecificationsFlag().equals(HcIsFlagEnum.YES) && hcCommodity.getCommodityPrice() == null && zeroCount >= jsonArray.size()) {
//            throw new JeecgBootException("不能所有一级规格的二级规格里面都存在不填价格和价格为0的情况");
            throw new JeecgBootException("不能所有一级规格的二级规格里面都存在不填价格和价格小于0的情况");
        }
    }

    public void setInformation(HcCommodity param, HcMerchantCommission hcMerchantCommission) {
        //设置菜品价格
        if (param.getCommodityPrice() == null || param.getCommodityPrice().compareTo(new BigDecimal(0)) < 0) {
            BigDecimal commodityPrice = new BigDecimal(0);
            try {
                JSONArray jsonArray = JSON.parseArray(param.getCommoditySpecifications());
                JSONArray jsonArrayCache = new JSONArray();

                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    JSONArray child = jsonObject.getJSONArray("child");
                    JSONArray childCache = new JSONArray();

                    BigDecimal price = child.getJSONObject(0).getBigDecimal("price");
                    commodityPrice = commodityPrice.add(price);

                    if (hcMerchantCommission != null) {
                        if (price.compareTo(new BigDecimal(0))>0){
                            commodityPrice = commodityPrice.add(hcMerchantCommissionService.getCommission(hcMerchantCommission, price));
                        }
                        for (int i1 = 0; i1 < child.size(); i1++) {
                            JSONObject childJSONObject = child.getJSONObject(i1);
                            BigDecimal bigDecimal = childJSONObject.getBigDecimal("price");
                            if (bigDecimal.compareTo(new BigDecimal(0))>0){
                                bigDecimal = bigDecimal.add(hcMerchantCommissionService.getCommission(hcMerchantCommission, bigDecimal));
                            }
                            childJSONObject.put("price", bigDecimal);
                            childCache.add(childJSONObject);
                        }

                        jsonObject.put("child", childCache);
                        jsonArrayCache.add(jsonObject);
                    }
                }

                param.setCommodityPriceCache(commodityPrice);

                if (jsonArrayCache.size() > 0) {
                    param.setCommoditySpecifications(jsonArrayCache.toJSONString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            if (hcMerchantCommission != null && param.getCommodityPrice().compareTo(new BigDecimal(0)) > 0) {
                param.setCommodityPriceCache(param.getCommodityPrice().add(hcMerchantCommissionService.getCommission(hcMerchantCommission, param.getCommodityPrice())));
            } else {
                param.setCommodityPriceCache(param.getCommodityPrice());
            }
        }

        Integer remainingQuantity = this.getRemainingQuantity(param);
        param.setRemainingQuantity(remainingQuantity);
    }

    public void setLimitBuy(HcCommodity param) {
        JSONObject yongShanTuanTime = HcUtils.getYongShanTuanTime();
        String beginTime = yongShanTuanTime.getString("beginTime");
        String endTime = yongShanTuanTime.getString("endTime");
        String redisKey = RedisConstant.HC_COMMODITY_LIMITBUY + beginTime + endTime + '_' + param.getId();

        if (param.getLimitBuy() > -1) {
            redisUtil.set(redisKey, param.getLimitBuy(), 60 * 60 * 24);
        } else {
            redisUtil.del(redisKey);
        }
    }

    public Integer getRemainingQuantity(HcCommodity param) {
        JSONObject yongShanTuanTime = HcUtils.getYongShanTuanTime();
        String beginTime = yongShanTuanTime.getString("beginTime");
        String endTime = yongShanTuanTime.getString("endTime");
        String redisKey = RedisConstant.HC_COMMODITY_LIMITBUY + beginTime + endTime + '_' + param.getId();

        Integer remainingQuantity = 0;

        if (param.getLimitBuy() > -1) {
            if (redisUtil.hasKey(redisKey)) {
                remainingQuantity = (Integer) redisUtil.get(redisKey);
            } else {
                redisUtil.set(redisKey, param.getLimitBuy(), 60 * 60 * 24);
                remainingQuantity = param.getLimitBuy();
            }
        }

        return remainingQuantity;
    }

    public HcCommodity checkSpecifications(HcCommodity param, String addressId, String specificationsName) {
        HcSiteAddressDetails siteAddressDetails = hcSiteAddressDetailsService.getById(addressId);

        if (siteAddressDetails == null) {
            throw new JeecgBootException("未查询到地址信息，请重新选择地址");
        }

        HcMerchantCommission hcMerchantCommission = hcMerchantCommissionService.getOne(new LambdaQueryWrapper<HcMerchantCommission>()
                .eq(HcMerchantCommission::getAddressId, addressId)
                .eq(HcMerchantCommission::getMerchantId, param.getMerchantId())
        );

        HcCommodity result = new HcCommodity();

        //根据规格计算价格
        BigDecimal commodityPrice = new BigDecimal(0);
        BigDecimal originalPrice = new BigDecimal(0);
        BigDecimal commission = new BigDecimal(0);

        //根据规格名称匹配到的规格json存在这里  作为保存使用  方便查看数据
        JSONArray commoditySpecifications = new JSONArray();

        //根据规格名称匹配到的规格名称存在这里 再保存一次是为了保证规格显示的顺序一直 方便分组查看订单份数
        List<String> sortNameList = new ArrayList<>();

        if (StringUtils.isNotBlank(specificationsName)) {
            //规格名称集合
            List<String> nameList = Arrays.asList(specificationsName.split(","));

            //规格json集合
            JSONArray jsonArray = JSON.parseArray(param.getCommoditySpecifications());

            if (nameList.size() != jsonArray.size()) {
                return null;
            }

            //规格名称匹配次数
            int checkNum = 0;

            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray child = jsonObject.getJSONArray("child");
                JSONArray childCache = new JSONArray();

                for (int i1 = 0; i1 < child.size(); i1++) {
                    JSONObject childJSONObject = child.getJSONObject(i1);
                    String name = childJSONObject.getString("name");
                    BigDecimal price = childJSONObject.getBigDecimal("price");

                    if (nameList.contains(name)) {
                        childCache.add(childJSONObject);

                        if (price != null) {
                            BigDecimal commission1 = new BigDecimal(0);
                            if(price.compareTo(new BigDecimal(0))>0){
                                commission1 = commission1.add(hcMerchantCommissionService.getCommission(hcMerchantCommission, price));
                            }
//                            BigDecimal commission1 = hcMerchantCommissionService.getCommission(hcMerchantCommission, price);
                            commodityPrice = commodityPrice.add(price).add(commission1);
                            originalPrice = originalPrice.add(price);
                            commission = commission.add(commission1);
                        }

                        checkNum++;
                        sortNameList.add(name);
                    }
                }

                if (checkNum != i + 1) {
                    return null;
                }

                jsonObject.put("child", childCache);
                commoditySpecifications.add(jsonObject);
            }

            if (checkNum != nameList.size()) {
                return null;
            }
        }

        if (param.getCommodityPrice() != null && param.getCommodityPrice().compareTo(new BigDecimal(0)) > 0) {
            BigDecimal commission1 = hcMerchantCommissionService.getCommission(hcMerchantCommission, param.getCommodityPrice());
            result.setCommodityPrice(param.getCommodityPrice().add(commission1));
            result.setOriginalPrice(param.getCommodityPrice());
            result.setCommission(commission1);
        } else {
            result.setCommodityPrice(commodityPrice);
            result.setOriginalPrice(originalPrice);
            result.setCommission(commission);
        }

        result.setCommoditySpecifications(commoditySpecifications.toJSONString());
        result.setSpecifications(StringUtils.join(sortNameList, "+"));
        return result;
    }
    public HcCommodity checkSpecificationsNew(HcCommodity param, String addressId, String specificationsName) {
        HcSiteAddressDetails siteAddressDetails = hcSiteAddressDetailsService.getById(addressId);

        if (siteAddressDetails == null) {
            throw new JeecgBootException("未查询到地址信息，请重新选择地址");
        }

        HcMerchantCommission hcMerchantCommission = hcMerchantCommissionService.getOne(new LambdaQueryWrapper<HcMerchantCommission>()
                .eq(HcMerchantCommission::getAddressId, addressId)
                .eq(HcMerchantCommission::getMerchantId, param.getMerchantId())
        );

        HcCommodity result = new HcCommodity();

        //根据规格计算价格
        BigDecimal commodityPrice = new BigDecimal(0);
        BigDecimal originalPrice = new BigDecimal(0);
        BigDecimal commission = new BigDecimal(0);

        //根据规格名称匹配到的规格json存在这里  作为保存使用  方便查看数据
        JSONArray commoditySpecifications = new JSONArray();

        //根据规格名称匹配到的规格名称存在这里 再保存一次是为了保证规格显示的顺序一直 方便分组查看订单份数
        List<String> sortNameList = new ArrayList<>();

        if (StringUtils.isNotBlank(specificationsName)) {
            //规格名称集合
            List<String> nameList = Arrays.asList(specificationsName.split(","));

            //规格json集合
            JSONArray jsonArray = JSON.parseArray(param.getCommoditySpecifications());

            if (nameList.size() != jsonArray.size()) {
                return null;
            }

            //规格名称匹配次数
            int checkNum = 0;

            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray child = jsonObject.getJSONArray("child");
                JSONArray childCache = new JSONArray();

                for (int i1 = 0; i1 < child.size(); i1++) {

                    JSONObject childJSONObject = child.getJSONObject(i1);
                    String name = childJSONObject.getString("name");
                    BigDecimal price = childJSONObject.getBigDecimal("price");

                    if (nameList.contains(name)) {
                        childCache.add(childJSONObject);

                        if (price != null) {
                            BigDecimal commission1 = hcMerchantCommissionService.getCommission(hcMerchantCommission, price);
                            commodityPrice = commodityPrice.add(price).add(commission1);
                            originalPrice = originalPrice.add(price);
                            commission = commission.add(commission1);
                        }

                        checkNum++;
                        sortNameList.add(name);
                    }
                }

                if (checkNum != i + 1) {
                    return null;
                }


                jsonObject.put("child", childCache);
                commoditySpecifications.add(jsonObject);
            }

            if (checkNum != nameList.size()) {
                return null;
            }
        }

        if (param.getCommodityPrice() != null && param.getCommodityPrice().compareTo(new BigDecimal(0)) > 0) {
            BigDecimal commission1 = hcMerchantCommissionService.getCommission(hcMerchantCommission, param.getCommodityPrice());
            result.setCommodityPrice(param.getCommodityPrice().add(commission1));
            result.setOriginalPrice(param.getCommodityPrice());
            result.setCommission(commission1);
        } else {
            result.setCommodityPrice(commodityPrice);
            result.setOriginalPrice(originalPrice);
            result.setCommission(commission);
        }

        result.setCommoditySpecifications(commoditySpecifications.toJSONString());
        result.setSpecifications(StringUtils.join(sortNameList, "+"));
        return result;
    }
}
